package net.melon.agency.inst.ssh.service.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;

import net.esj.basic.core.engine.tools.crypt.inst.PwdEncryptor;
import net.esj.basic.core.engine.util.enumeration.EnumProvidersFactory;
import net.esj.basic.core.engine.util.enumeration.EnumVo;
import net.esj.basic.core.view.tools.searcher.Searcher;
import net.esj.basic.core.view.tools.searcher.SearcherUtils;
import net.esj.basic.dao.jdbc.JdbcDao;
import net.esj.basic.dao.querybuilder.QueryBuilder;
import net.esj.basic.exception.MelonException;
import net.esj.basic.pojo.op.Operator;
import net.esj.basic.service.impl.DefaultServiceImpl;
import net.esj.basic.utils.Pagination;
import net.esj.basic.utils.StringUtils;
import net.melon.agency.inst.ssh.service.AgencyService;
import net.melon.agency.inst.ssh.service.UserService;
import net.melon.agency.pojo.Agency;
import net.melon.agency.pojo.AgencyGroup;
import net.melon.agency.pojo.AgencyUser;
import net.melon.jdbc.core.RowMapper;

@Singleton
@Named("agencyService")
public class AgencyServiceImpl extends DefaultServiceImpl implements
		AgencyService {
	@Resource
	private UserService userService;
	@Resource
	private PwdEncryptor pwdEncryptor;
	@Resource
	private EnumProvidersFactory enumProvidersFactory;
	
	@Override
	public Agency saveAgency(Agency agency , Operator operator) {
		if(!checkAgencyExist(agency)){
			agency.setCreatorId(operator.getId().toString());
			agency.setCreatorType(operator.getMType());
			save(agency);
		}else{
			throw new MelonException("代理商名字重复！");
		}
		return agency;
	}

	@Override
	public Agency updateAgency(Agency agency) {
		update(agency);
		return agency;
	}

	@Override
	public void deleteAgency(String agencyId) {
		Agency agency = getAgency(agencyId);
		agency.setDeleted(true);
		update(agency);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<Agency> pageAgency(Pagination pagination,String parentName) {
		
		
		if(StringUtils.hasText(parentName)){
			String start_sql="SELECT A1.* FROM AT_AGENCY AS A1,AT_AGENCY AS A2 WHERE A1.PARENT_ID = A2.ID ";
			StringBuilder sb = new StringBuilder(start_sql);
			sb.append(" AND A2.NAME LIKE '%").append(parentName).append("%'");
			String end_sql=sb.toString();
			
			pagination = ((JdbcDao)dao).queryPage(end_sql, new RowMapper<Agency>(){
				@Override
				public Agency mapRow(ResultSet rs, int arg1) throws SQLException {
					Agency agency = new Agency();
					agency.setId(rs.getString("ID"));
					agency.setName(rs.getString("NAME"));
					agency.setAddress(rs.getString("ADDRESS"));
					agency.setMobile(rs.getString("MOBILE"));
					agency.setLinkMan(rs.getString("LINK_MAN"));
					agency.setGmtCreate(rs.getDate("GMT_CREATE"));
					agency.setState(rs.getInt("STATE"));
					agency.setTradeChannel(rs.getInt("TRADE_CHANNEL"));
					agency.setParentId(rs.getString("PARENT_ID"));
					agency.setDeleted(rs.getBoolean("DELETED"));
					agency.setCreatorId(rs.getString("CREATOR_ID"));
					agency.setCreatorType(rs.getString("CREATOR_TYPE"));
					
					return agency;
				}
				
			}, pagination, "");
		}else{
			pagination = queryPageByQueryBuilder(pagination);
		}
		
		
		for(Object o: pagination.getRows()){
			Agency ag = (Agency)o;
			if(StringUtils.hasText(ag.getParentId())){
				ag.setParent(get(ag.getParentId(), Agency.class));
			}
		}
		return pagination;
	}

	@Override
	public Agency getAgency(String id) {
		Agency agency =  get(id, Agency.class);
		if(StringUtils.hasText(agency.getParentId())){
			agency.setParent(get(agency.getParentId(), Agency.class));
		}
		return agency;
	}

	@Override
	public List<Agency> listAgency(Searcher searcher) {
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		if(searcher!=null){
			SearcherUtils.appendQueryBuilder(searcher, qb);
		}
		return queryListByQueryBuilder(qb);
	}
		
	@Override
	public boolean checkAgencyExist(Agency agency){
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		qb.eq("name", agency.getName());
		if(StringUtils.hasText(agency.getId())){
			qb.notEq("id", agency.getId());
		}
		int count = queryCountByQueryBuilder(qb);
		if(count > 0){
			return true;
		}else{
			return false;
		}
	}
	
	
	@Override
	public boolean checkAgencyUserNameExist(String name){
		QueryBuilder<AgencyUser> qb = createQueryBuilder(AgencyUser.class);
		qb.eq("name", name);
		int count = queryCountByQueryBuilder(qb);
		if(count > 0 ){
			return true;
		}else{
			return false;
		}
	}
	
	private String defaultGroupId(){
		String str = "402881e9490255160149025b245d0000";
		List<EnumVo> list =enumProvidersFactory.findEnumVo("DEFAULT_AGENCY_GROUP_ID");
		if(list.size()>0){
			return list.get(0).getEnumValue();
		}else{
			return str;
		}
	}
	
	private AgencyGroup getDefaultAgencyGroup(){
		QueryBuilder<AgencyGroup> qb = createQueryBuilder(AgencyGroup.class);
		qb.eq("id", defaultGroupId()).isNull("agency");
		List<AgencyGroup> list = queryListByQueryBuilder(qb);
		if(list.size()>0){
			return list.get(0);
		}else{
			return null;
		}
	}
	
	@Override
	public Agency getAgencyByName(String name){
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		qb.eq("name", name);
		List<Agency> list = queryListByQueryBuilder(qb);
		if(list.size()>0){
			return list.get(0);
		}else{
			return null;
		}
		
	}
	
	private boolean chackHasChild(Agency agency){
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		qb.eq("parentId", agency.getId());
		int count = queryCountByQueryBuilder(qb);
		if(count>0){
			return true;
		}else{
			return false;
		}
	}
	
	private List<Agency> getUnderAgency(Agency agency){
		List<Agency> result = new ArrayList<Agency>();
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		qb.eq("parentId", agency.getId());
		List<Agency> childs = queryListByQueryBuilder(qb);
		for(Agency age : childs){
			result.add(age);
			if(!chackHasChild(age)){
				result.addAll(getUnderAgency(age));
			}
		}
		return result;
	}
	
	@Override
	public List<Agency> getAllUnderAgencyByOperator(Operator operator){
		List<Agency> list = new ArrayList<Agency>();
		if(operator.getMType().equals(AgencyUser.MOBJECT_TYPE)){
			AgencyUser agencyUser = getFull(operator.getId().toString(), AgencyUser.class, new String[]{"agency"});
			list = getUnderAgency(agencyUser.getAgency());
			return list;
		}else{
			return list;
		}
	}
	
	@Override
	public List<String> getAgencyLowerLevel(String parentId) {
		List<String> str = new ArrayList<String>();
		str = newGetAllLowerLevel(parentId, true);
		return str;
	}
	
	private List<String> newGetAllLowerLevel(String parentId , boolean withSelf){
		List<String> ids = new ArrayList<String>();
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		qb.eq("parentId", parentId);
		List<Agency> list = queryListByQueryBuilder(qb);
		for(Agency agency : list){
			ids.add(agency.getId());
			ids.addAll(getLowerLevel(agency));
		}
		if(withSelf){
			ids.add(parentId);
		}
		return ids;
	}
	
	private List<String> getLowerLevel(Agency agency){
		List<String> ids = new ArrayList<String>();
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		qb.eq("parentId", agency.getId());
		List<Agency> list = queryListByQueryBuilder(qb);
		for(Agency agency2 : list){
			ids.add(agency2.getId());
			ids.addAll(getLowerLevel(agency2));
		}
		return ids;
	}

	@Override
	public List<Agency> listAgencyByCity(Long citySession) {
		QueryBuilder<Agency> qb = createQueryBuilder(Agency.class);
		qb.eq("regionId", citySession);
		return queryListByQueryBuilder(qb);
	}

}
